<template>
  <div class="reservation-container">
    <!-- 搜索和操作按钮合并区域 -->
    <div class="search-and-action">
      <div class="search-card">
        <el-form :inline="true" :model="reservationSearchModel" class="demo-form-inline" ref="reservationSearchForm">
          <el-form-item label="筛选：" prop="memberName">
            <div class="search-input-group">
              <el-input
                  v-model="reservationSearchModel.memberName"
                  placeholder="请输入会员姓名"
                  :prefix-icon="Search"
                  class="search-input"
                  clearable
                  @clear="reset"
              />
              <el-input
                  v-model="reservationSearchModel.courseName"
                  placeholder="请输入课程名"
                  :prefix-icon="Search"
                  class="search-input"
                  clearable
                  @clear="reset"
              />
              <div class="search-buttons">
                <el-button type="primary" :icon="Search" @click="searchAll()" class="search-btn">查询</el-button>
                <el-button type="default" :icon="RefreshRight" @click="reset" class="reset-btn">重置</el-button>
              </div>
            </div>
          </el-form-item>
        </el-form>
      </div>
    </div>

    <!-- 表格区域 -->
    <div class="table-container">
      <el-table
          :data="reservations"
          height="100%"
          style="width: 100%"
          stripe
          border
          class="table-grid"
          @row-click="tblRowClick"
          ref="tblRef"
          :row-class-name="tableRowClassName"
          v-loading="loading"
      >
        <el-table-column type="selection" width="80" align="center"/>
        <el-table-column prop="reservationId" label="预约ID" width="100" fixed/>
        <el-table-column prop="memberName" label="会员" width="160">
          <template #default="scope">
            {{ scope.row.memberName }} - {{getMemberTypeByMemberId(scope.row.memberId)}}
          </template>
        </el-table-column>
        <el-table-column prop="courseName" label="课程" width="200">
          <template #default="scope">
            {{ scope.row.courseName }} - {{ getCoachNameByCourseId(scope.row.courseId) }}-{{getCourseTypeByCourseId(scope.row.courseId)}}
          </template>
        </el-table-column>
        <el-table-column prop="reserveTime" label="预约时间" width="210"/>
        <el-table-column prop="status" label="状态" width="140">
          <template #default="scope">
            <el-tag v-if="scope.row.status === 1" type="success" class="status-tag confirmed">已完成</el-tag>
            <el-tag v-else-if="scope.row.status === 0" type="warning" class="status-tag pending">已预约</el-tag>
            <el-tag v-else type="info" class="status-tag canceled">已取消</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="350" align="center" fixed="right">
          <template #default="scope">
            <el-button type="primary" size="small" @click.stop="editRow(scope.row)" class="table-btn edit">编辑</el-button>
            <el-button type="danger" size="small" @click.stop="removeRow(scope.row)" class="table-btn delete">删除
            </el-button>
            <el-button type="success" size="small" @click.stop="confirmed(scope.row)" class="table-btn confirm">已完成</el-button>
            <el-button type="danger" size="small" @click.stop="cancel(scope.row)" class="table-btn cancel">已取消</el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>

    <!-- 分页区域 -->
    <div class="pagination-container">
      <el-pagination
          v-model:current-page="reservationPi.pageNo"
          v-model:page-size="reservationPi.pageSize"
          :page-sizes="[10, 20, 30, 40, 50]"
          layout="total, sizes, prev, pager, next, jumper"
          :total="reservationPi.total"
          class="reservation-pi"
          @change="reservationPiChange"
          background=true
      />
    </div>

    <!-- 添加/修改对话框 -->
    <el-dialog
        v-model="reservationDlgShow"
        :title="reservationDlgTitle"
        width="600px"
        :close-on-click-modal="false"
        draggable
        show-close
        align-center
        @close="resetReservationForm"
        class="reservation-dialog"
    >
      <el-form
          label-width="100"
          label-position="right"
          :model="reservationModel"
          ref="reservationForm"
          :rules="rules"
          class="reservation-form"
      >
        <el-form-item label="会员" prop="memberId">
          <el-select v-model="reservationModel.memberId" placeholder="请选择会员" class="w-100">
            <el-option
                v-for="member in enableMember"
                :key="member.id"
                :label="`${member.name} - ${getMemberTypeByMemberId(member.id)}`"
                :value="member.id"
            />
          </el-select>
        </el-form-item>

        <el-form-item label="课程" prop="courseId">
          <el-select v-model="reservationModel.courseId" placeholder="请选择课程" class="w-100">
            <el-option
                v-for="course in courses"
                :key="course.courseId"
                :label="`${course.courseName}-${getCoachNameByCourseId(course.courseId)}-${getCourseTypeByCourseId(course.courseId)}`"
                :value="course.courseId"
            />
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitEdit" class="dialog-btn confirm">确定</el-button>
          <el-button @click="reservationDlgShow=false" class="dialog-btn cancel">取消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<style scoped>
.reservation-container {
  padding: 20px;
  background-color: #f5f7fa;
  min-height: 100vh;
  box-sizing: border-box;
}

/* 搜索和操作按钮合并区域 */
.search-and-action {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
  gap: 15px;
  flex-wrap: wrap;
}

/* 搜索区域样式 */
.search-card {
  background: #fff;
  padding: 15px 20px;
  border-radius: 8px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
  flex: 1;
  min-width: 300px;
}

.search-input-group {
  display: flex;
  align-items: center;
  gap: 8px;
}

.search-input {
  transition: all 0.3s ease;
  flex: 1;
  min-width: 200px;
  height: 40px;
}

.search-input:focus-within {
  box-shadow: 0 0 0 2px rgba(145, 163, 255, 0.2);
}

.search-buttons {
  display: flex;
  gap: 8px;
}

/* 操作按钮样式 */

.search-btn {
  transition: all 0.2s ease;
  border-radius: 4px;
  height: 40px;
  background-color: #409eff;
}

.reset-btn {
  transition: all 0.2s ease;
  border-radius: 4px;
  height: 40px;
  background-color: #f5f7fa;
  color: #606266;
  border-color: #dcdfe6;
}

.search-btn:hover, .reset-btn:hover {
  transform: translateY(-1px);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

/* 表格区域样式 */
.table-container {
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
  overflow: hidden;
  margin-bottom: 15px;
}

.table-grid {
  margin-top: 0;
  border: none;
  font-size: 14px;
}

.el-table th {
  background-color: #f5f7fa;
  font-weight: 500;
  color: #303133;
  height: 48px;
}

.el-table td {
  height: 48px;
}

.el-table tr:hover > td {
  background-color: #f0f7ff !important;
}

.tableRowClassName {
  transition: background-color 0.2s ease;
}

/* 表格内标签样式 */
.status-tag {
  border-radius: 4px;
  padding: 2px 8px;
  font-size: 12px;
}

.confirmed {
  background-color: #f6ffed;
  color: #52c41a;
  border-color: #52c41a;
}

.pending {
  background-color: #fffbe6;
  color: #faad14;
  border-color: #faad14;
}

.canceled {
  background-color: #fff1f0;
  color: #ff4d4f;
  border-color: #ff4d4f;
}

/* 表格操作按钮 */
.table-btn {
  border-radius: 4px;
  margin: 0 3px;
  transition: all 0.2s ease;
  padding: 5px 10px;
}

.table-btn.edit {
  background-color: #409eff;
  border-color: #409eff;
}

.table-btn.delete {
  background-color: #f56c6c;
  border-color: #f56c6c;
}

.table-btn:hover {
  transform: scale(1.05);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}

/* 分页区域 */
.pagination-container {
  background: #fff;
  padding: 15px 20px;
  border-radius: 8px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
}

.reservation-pi {
  margin-top: 0;
  text-align: right;
}

/* 对话框样式 */
.reservation-dialog {
  border-radius: 8px;
  overflow: hidden;
}

.reservation-form {
  margin-top: 15px;
}

.w-100 {
  width: 100%;
}

/* 对话框按钮 */
.dialog-footer {
  display: flex;
  justify-content: center;
  gap: 15px;
  padding-top: 10px;
}

.dialog-btn {
  width: 100px;
  transition: all 0.2s ease;
}

.dialog-btn.confirm {
  background-color: #409eff;
  border-color: #409eff;
}

.dialog-btn.cancel {
  background-color: #f5f5f5;
  color: #333;
}

.dialog-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}

/* 动画效果 */
.el-button, .el-input, .el-select, .el-date-picker, .el-table, .el-dialog {
  transition: all 0.2s ease-in-out;
}

.el-table__row {
  animation: fadeIn 0.3s ease-in-out;
}

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(5px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 响应式调整 */
@media (max-width: 768px) {
  .search-and-action {
    flex-direction: column;
    align-items: stretch;
  }


  .search-input-group {
    flex-direction: column;
    align-items: stretch;
  }

  .search-buttons {
    width: 100%;
  }

  .search-btn, .reset-btn {
    flex: 1;
    width: 50%;
  }
}
</style>

<script setup>
import {onMounted, ref, reactive, toRaw, nextTick, computed} from "vue"
import api from "@/util/api"
import {CirclePlus, Delete, Edit, Plus, RefreshRight, Search} from "@element-plus/icons-vue";
import {ElMessage, ElMessageBox} from "element-plus";
import {cloneDeep} from "lodash";
import dayjs from "dayjs";

onMounted(async () => {
  searchAll();
  loadMembers();
  loadCourses();
});

let reservations = ref([]);
let loading = ref(false);
let reservationPi = reactive({
  pageNo: 1,
  pageSize: 10,
  total: 0
});

let reservationSearchModel = ref({
  memberName: null,
  courseName: null,
});

let reservationSearchForm = ref();
let reservationDlgTitle = ref("新增预约");
let reservationDlgShow = ref(false);
let tblRef = ref();

let reservationModel = ref({
  reservationId: null,
  memberId: null,
  courseId: null,
  reserveTime: null,
  status: 0 // 改为数字类型默认值
});

let members = ref([]);
let courses = ref([]);

let mode = "add";
let reservationForm = ref();

// 根据课程ID获取教练名
const getCoachNameByCourseId = (courseId) => {
  const course = courses.value.find(c => c.courseId === courseId);
  return course ? course.coachName : '';
};
//根据课程id获取课程时间
const getCourseTimeByCourseId = (courseId) => {
  const course = courses.value.find(c => c.courseId === courseId);
  return course ? course.schedule: '';
}
//根据课程id获取课程类型
const getCourseTypeByCourseId = (courseId) => {
  const course = courses.value.find(c => c.courseId === courseId);
  return course ? course.type: '';
}
//根据会员id获取会员类型
const getMemberTypeByMemberId = (memberId) => {
  const member = members.value.find(m => m.id === memberId);
  return member ? member.membershipType: '';
}

//校验规则
const rules = {
  memberId: [
    {required: true, message: '请选择会员', trigger: 'change'}
  ],
  courseId: [
    {required: true, message: '请选择课程', trigger: 'change'}
  ],
  reserveTime: [
    {required: true, message: '请选择预约时间', trigger: 'change'}
  ],
  status: [
    {required: true, message: '请选择状态', trigger: 'change'}
  ]
};
//完成预约
async function confirmed(row) {
  let nowParams = toRaw(row);
  nowParams.status = 1;
  reservationModel.value = nowParams;
  let params = toRaw(reservationModel.value);
  //console.log(reservationModel.value);
  await api({
    url: "/reservation",
    method: "put",
    data: params
  });
  searchAll(reservationPi.pageNo, reservationPi.pageSize)
}
//取消预约
async function cancel(row) {
  let nowParams = toRaw(row);
  nowParams.status = 2;
  reservationModel.value = nowParams;
  let params = toRaw(reservationModel.value);
  await api({
    url: "/reservation",
    method: "put",
    data: params
  });
  searchAll(reservationPi.pageNo, reservationPi.pageSize)
}
//搜索
async function searchAll(pageNo = 1, pageSize = 10) {
  loading.value = true;
  try {
    let params = toRaw(reservationSearchModel.value);
    let resp = await api({
      url: "/reservation",
      method: "get",
      params: {
        pageNo,
        pageSize,
        ...params
      }
    });
    //console.log(resp);
    reservations.value = resp.data.records;
    reservationPi.pageSize = resp.data.size;
    reservationPi.total = resp.data.total;
    reservationPi.pageNo = resp.data.current;
  } catch (e) {
    ElMessage.error("获取预约失败");
  } finally {
    loading.value = false;
  }
}
//计算在会会员
const enableMember = computed(()=>{
  return members.value.filter(member => member.status === 1)
});

//分页
function reservationPiChange(pageNo, pageSize) {
  searchAll(pageNo, pageSize);
}
//重置
function reset() {
  reservationSearchForm.value.resetFields();
  searchAll();
}
//表格行点击事件
function tblRowClick(row) {
  tblRef.value.toggleRowSelection(row);
}

// 用于表格行样式的回调函数
function tableRowClassName({row, rowIndex}) {
  return 'tableRowClassName';
}

async function removeByIds(ids) {
  try {
    await api({
      url: "/reservation",
      method: "delete",
      data: ids
    });
    ElMessage.success("删除成功")
    searchAll();
  } catch (e) {
    ElMessage({
      type: 'info',
      message: '删除失败',
    })
  }
}

function resetReservationForm() {
  reservationForm.value.resetFields();
}

function editRow(row) {
  reservationDlgShow.value = true;
  reservationDlgTitle.value = "修改预约信息";
  mode = "edit";
  nextTick(() => {
    // 确保编辑时状态为数字类型
    const editData = cloneDeep(toRaw(row));
    editData.status = Number(editData.status);
    reservationModel.value = editData;
  });
}

function submitEdit() {
  reservationForm.value.validate(async (valid) => {
    if (valid) {
      try {
        const isContained = courses.value.find(course => course.courseId === reservationModel.value.courseId);
        if(isContained){
          if(isContained.contain>=isContained.maxStudent){
            ElMessage.error("该课程已满");
            return;
          }
        }
        let params = toRaw(reservationModel.value);
        // 确保状态为数字类型
        params.status = Number(params.status);
       // console.log(params)
        let resp = await api({
          url: "/reservation",
          method: "put",
          data: params
        });
        if (resp.success) {
          reservationDlgShow.value = false;
          searchAll(reservationPi.pageNo, reservationPi.pageSize);
          ElMessage.success("修改成功");
        } else {
          ElMessage.error(resp.msg || "修改失败")
        }
      } catch (e) {
        ElMessage.error(e.msg || "修改失败")
      }
    }
  });
}

function removeRow(row) {
  ElMessageBox.confirm(
      '是否确认删除',
      '警告',
      {
        confirmButtonText: '是',
        cancelButtonText: '否',
        type: 'warning',
      }
  ).then(() => {
    removeByIds([row.reservationId]);
  }).catch(() => {
    ElMessage({
      type: 'info',
      message: '已取消删除',
    })
  })
}

// 获取会员列表
const loadMembers = async () => {
  try {
    const res = await api.get("/members/all");
    //console.log(res);
    members.value = res.data;
    //console.log(members.value);
  } catch (e) {
    ElMessage.error("获取会员列表失败");
  }
};

// 获取课程列表
const loadCourses = async () => {
  try {
    const res = await api.get("/course/all");
    //console.log(res);
    courses.value = res.data;
    console.log(courses.value);
  } catch (e) {
    ElMessage.error("获取课程列表失败");
  }
};
</script>
